<?php

namespace App\V3\V3_2_6\Services;

use App\V3\V3_2_6\Models\LogInStorageModel;
use App\V3\V3_2_6\Models\LogOutStorageModel;
use App\V3\V3_2_6\Models\LogPackageContentModel;
use App\V3\V3_2_6\Models\LogPackageModel;
use App\V3\V3_2_6\Models\MaterielsTypeModel;
use App\V3\V3_2_6\Models\OverflowBreakagePackageContentModel;
use App\V3\V3_2_6\Models\PackageModel;
use App\V3\V3_2_6\Models\SerialNumberModel;
use App\V3\V3_2_6\Models\StorageBatchModel;
use App\V3\V3_2_6\Models\StorageManageModel;
use App\V3\V3_2_6\Models\StorageModel;
use App\V3\V3_2_6\Models\CheckModel;
use App\V3\V3_2_6\Models\OverflowBreakageChecksModel;
use App\V3\V3_2_6\Models\OverflowBreakageDetailModel;
use App\V3\V3_2_6\Models\OverflowBreakageModel;
use App\Services\StorageManageService;
use App\V3\V3_2_6\Models\StorageShelfLocationModel;
use App\V3\V3_2_6\Models\StorageShelfModel;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class CheckService
{
    static public function agreeOrRefund1($data)
    {
        DB::beginTransaction();

        try {
            $overflowBreakageChecksModel = OverflowBreakageChecksModel::where(['o_b_main_id'=>$data['all_id'],'admin_id'=>$data['user_id']])->first();

            if($overflowBreakageChecksModel['status'] != 0) {
                return ['code' => 1, 'msg' => '不可重复操作', 'data' => ''];
            }
            if($data['status']) {
                return self::agree($data, $overflowBreakageChecksModel);
            }
            else {
                //更新审核人审核状态
                $overflowBreakageChecksModel->status = 2;
                $overflowBreakageChecksModel->refund_remark = isset($data['remark'])?$data['remark']:"";
                $overflowBreakageChecksModel->save();
                $obc = OverflowBreakageChecksModel::where(['status'=>0,'o_b_main_id'=>$data['all_id']])->first();
                if(!$obc){
                    OverflowBreakageModel::where('id',$data['all_id'])->update(['status'=>2]);//更新报溢报损审核状态
                    CheckModel::where('id',$data['id'])->update(['status'=>1]);//审批状态更新
                }
            }

            //更新临时审批人
            $model = CheckModel::where('id',$data['id'])->first();
            if($model['check_person_tmp']){
                $arr = explode(',',$model['check_person_tmp']);
                $userIdIndex = array_search($data['user_id'],$arr);
                unset($arr[$userIdIndex]);
                $model->check_person_tmp = implode(',',$arr);
                $model->save();
            }

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(Exception $e) {
            DB::rollBack();
            Log::debug('报溢报损审批:'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static public function agree($data)
    {
        $mainInfo = OverflowBreakageModel::with(['goodsInfo' => function($query) {
            $query->select(
                'overflow_breakage_detail.*',
                'a.cost',
                'b.id as materiel_class_id',
                'b.class_name',
                'b.class_no',
                'a.materiel_no'
            )
                ->leftJoin('materiel_type as a', 'a.id', '=', 'overflow_breakage_detail.materiel_type_id')
                ->leftJoin('materiel_class as b', 'b.id', '=', 'a.materiel_class_id')
            ;
        }])
            ->with(['packageInfo' => function($query) {
                $query->with(['packageContent' => function($query) {
                    $query->select(
                        'overflow_breakage_package_content.*',
                        'a.cost',
                        'a.materiel_name',
                        'a.type_name',
                        'a.materiel_no',
                        'b.storage_name',
                        'b.storage_address',
                        'c.id as materiel_class_id',
                        'c.class_name as materiel_class_name',
                        'c.class_no as materiel_class_no',
                        'd.in_storage_num',
                    )
                        ->leftJoin('materiel_type as a', 'a.id', '=', 'overflow_breakage_package_content.type_id')
                        ->leftJoin('storage as b', 'b.id', '=', 'overflow_breakage_package_content.storage_id')
                        ->leftJoin('materiel_class as c', 'c.id', '=', 'a.materiel_class_id')
                        ->leftJoin('storage_manage as d', 'd.id', '=', 'overflow_breakage_package_content.storage_manage_id');
                }]);
            }])
            ->where('id', $data['all_id'])->first()->toArray();

        DB::beginTransaction();

        try {
            //type 0:报溢;1:报损;
            if(!$mainInfo['type']) {
                $result = self::overflowAgree($data, $mainInfo);
            }
            else {
                $result = self::breakageAgree($data, $mainInfo);
            }

            CheckModel::where('id', $data['id'])->update(['status' => 1]);

            OverflowBreakageModel::where('id', $data['all_id'])->update(['status' => 1]);
            OverflowBreakageChecksModel::where('o_b_main_id', $data['all_id'])->update(['status' => 1]);

            DB::commit();
            return $result;
        }
        catch(Exception $e) {
            Log::debug('报溢报损审批同意异常'.var_export($e->getMessage(), true));
            DB::rollBack();
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static public function breakageAgree($data, $mainInfo)
    {
        if(!empty($mainInfo['goods_info'])) {
            $logOut = [];
            $batchOut = [];

            foreach($mainInfo['goods_info'] as $value) {
                if(!empty($value['serial_number'])) {
                    self::serialMaterielBreakage($value, $data);
                }
                else {

                    if(!empty($value['batch_info']) && $value['batch_info'] != '[]') {

                        self::serialBatchBreakage($value['batch_info'], $data);
                    }
                    else {

                        if($data['is_use_shelf']) {

                            $checkStorageInfo = StorageManageModel::where([
                                'delete_flag' => 0,
                                'type_id' => $value['materiel_type_id'],
                                'location_id' => $value['shelf_location_id']
                            ])->first();
                        }
                        else {

                            $checkStorageInfo = StorageManageModel::where([
                                'delete_flag' => 0,
                                'type_id' => $value['materiel_type_id'],
                                'storage_id' => $value['warehouse_id']
                            ])->first();
                        }

                        if(empty($checkStorageInfo)) {
                            throw new Exception('无效库存，无法报损');
                        }

                        if($checkStorageInfo['in_storage_num'] < $value['num']) {
                            throw new Exception('库存数不足，无法报损');
                        }

                        if($checkStorageInfo['virtual_storage_num'] < $value['num']) {
                            throw new Exception('可用库存数不足，无法报损');
                        }

                        $materielOut[] = [
                            'id' => $checkStorageInfo['id'],
                            'in_storage_num' => $checkStorageInfo['in_storage_num'] - $value['num'],
                            'virtual_storage_num' => $checkStorageInfo['virtual_storage_num'] - $value['num'],
                        ];

                        $batchInfo = StorageBatchModel::where('storage_manage_id', $checkStorageInfo['id'])
                            ->where('batch_left_num', '>=', $value['num'])->orderBy('batch_left_num', 'desc')->first();

                        if(!empty($batchInfo)) {
                            $batchOut[] = [
                                'id' => $batchInfo['id'],
                                'batch_left_num' => $batchInfo['batch_left_num'] - $value['num'],
                            ];
                        }

                        $logOut[] = [
                            'type' => 0,
                            'storage_batch_id' => empty($batchInfo['id'])?0:$batchInfo['id'],
                            'storage_id' => $checkStorageInfo['storage_id'],
                            'storage_name' => $checkStorageInfo['storage_name'],
                            'storage_address' => $checkStorageInfo['storage_address'],
                            'curr_storage_manage_id' => $checkStorageInfo['id'],
                            'materiel_class_id' => $checkStorageInfo['materiel_class_id'],
                            'materiel_class_name' => $checkStorageInfo['class_name'],
                            'materiel_class_no' => $checkStorageInfo['class_no'],
                            'materiel_type_id' => $checkStorageInfo['type_id'],
                            'materiel_name' => $checkStorageInfo['materiel_name'],
                            'type_name' => $checkStorageInfo['type_name'],
                            'materiel_no' => $checkStorageInfo['materiel_no'],
                            'operate_num' => $value['num'],
                            'last_storage_num' => $checkStorageInfo['in_storage_num'],
                            'next_storage_num' => $checkStorageInfo['in_storage_num'] - $value['num'],
                            'sell_price' => $checkStorageInfo['materiel_mean_cost'],
                            'materiel_mean_cost' => $checkStorageInfo['materiel_mean_cost'],
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id'],
                            'out_storage_time' => time(),
                            'created_at' => time(),
                            'all_id_type' => 1,
                            'all_id' => $data['all_id'],
                            'is_cancel' => 0
                        ];
                    }
                }
            }

            if(!empty($logOut)) {
                LogOutStorageModel::insert($logOut);
            }

            if(!empty($batchOut)) {
                batch()->update(new StorageBatchModel, $batchOut, 'id');
            }

            if(!empty($materielOut)) {
                batch()->update(new StorageManageModel, $materielOut, 'id');
            }
        }

        if(!empty($mainInfo['package_info'])) {

            $breakagePackageLog = [];

            foreach($mainInfo['package_info'] as $value) {
                $packageInfo = PackageModel::where('id', $value['package_id'])->first();

                $logId = LogPackageModel::insertGetId([
                    'package_id' => $value['package_id'],
                    'package_name' => $packageInfo['package_name'],
                    'num' => $value['num'],
                    'all_id_type' => 1,
                    'all_id' => $data['all_id'],
                    'user_id' => $data['user_id'],
                    'main_id' => $data['main_id'],
                    'created_at' => time()
                ]);

                foreach($value['package_content'] as $val) {
                    if(!empty($val['serial_number'])) {
                        self::breakagePakcageSerial($val, $data, $logId);
                    }
                    else {
                        if($data['out_way']) {
                            self::breakagePakcageBatch($val, $data, $logId);
                        }
                        else {
                            self::normal($val, $data, $logId);
                        }
                    }
                }
            }
        }

        return ['code' => 0, 'msg' => 'success', 'data' => ''];
    }

    public static function normal($packageContentInfo, $data, $logId)
    {
        $storageManageInfo = StorageManageModel::where('id', $packageContentInfo['storage_manage_id'])->first();

        if($storageManageInfo['in_storage_num'] < $packageContentInfo['total_num']) {
            throw new Exception('库存数量不足，无法报损');
        }

        if($storageManageInfo['virtual_storage_num'] < $packageContentInfo['total_num']) {
            throw new Exception('可用库存数不足，无法报损');
        }

        StorageManageModel::where('id', $packageContentInfo['storage_manage_id'])
            ->update([
                'in_storage_num' => DB::raw('in_storage_num - '.$packageContentInfo['total_num']),
                'virtual_storage_num' => DB::raw('virtual_storage_num - '.$packageContentInfo['total_num']),
            ]);

        $logPackageContent = [
            'log_package_id' => $logId,
            'package_id' => $packageContentInfo['package_id'],
            'storage_id' => $packageContentInfo['storage_id'],
            'storage_name' => $packageContentInfo['storage_name'],
            'storage_address' => $packageContentInfo['storage_address'],
            'materiel_class_id' => $packageContentInfo['materiel_class_id'],
            'materiel_class_name' => $packageContentInfo['materiel_class_name'],
            'materiel_class_no' => $packageContentInfo['materiel_class_no'],
            'materiel_type_id' => $packageContentInfo['type_id'],
            'materiel_name' => $packageContentInfo['materiel_name'],
            'type_name' => $packageContentInfo['type_name'],
            'materiel_no' => $packageContentInfo['materiel_no'],
            'operate_num' => $packageContentInfo['total_num'],
            'shelf_id' => $packageContentInfo['shelf_id'],
            'location_id' => $packageContentInfo['shelf_location_id'],
            'out_storage_manage_id' => $packageContentInfo['storage_manage_id'],
            'last_storage_num' => $packageContentInfo['in_storage_num'],
            'next_storage_num' => $packageContentInfo['in_storage_num'] - $packageContentInfo['total_num'],
            'all_id_type' => 2,
            'all_id' => $data['all_id'],
            'user_id' => $data['user_id'],
            'main_id' => $data['main_id'],
            'created_at' => time()
        ];

        LogPackageContentModel::insert($logPackageContent);

        return true;
    }

    static public function breakagePakcageBatch($packageContentInfo, $data, $logId)
    {
        $batch = json_decode($packageContentInfo['batch_info'], true);

        $batchOut = [];
        $storageManageOut = [];
        $logPackageContent = [];

        foreach($batch as $value) {
            $checkBatch = StorageBatchModel::where('id', $value['batch_id'])->first();

            if($checkBatch['batch_left_num'] < $value['num']) {
                throw new Exception('批次号:'.$checkBatch['batch_no'].'剩余批次数量不足，当前剩余:'.$checkBatch['batch_left_num']);
            }

            $storageManageInfo = StorageManageModel::where('id', $value['storage_manage_id'])->where('delete_flag', 0)->first();

            if(empty($storageManageInfo)) {
                throw new Exception('无效库存信息,无法报损');
            }

            if($storageManageInfo['in_storage_num'] < $value['num']) {
                throw new Exception('库存数不足，无法报损');
            }

            if($storageManageInfo['virtual_storage_num'] < $value['num']) {
                throw new Exception('可用库存数不足，无法报损');
            }

            $batchOut[] = [
                'id' => $checkBatch['id'],
                'batch_left_num' => $checkBatch['batch_left_num'] - $value['num']
            ];

            $storageManageOut[] = [
                'id' => $storageManageInfo['id'],
                'virtual_storage_num' => $storageManageInfo['virtual_storage_num'] - $value['num'],
                'in_storage_num' => $storageManageInfo['in_storage_num'] - $value['num'],
            ];

            $logPackageContent[] = [
                'log_package_id' => $logId,
                'package_id' => $packageContentInfo['package_id'],
                'storage_id' => $packageContentInfo['storage_id'],
                'storage_name' => $packageContentInfo['storage_name'],
                'storage_address' => $packageContentInfo['storage_address'],
                'materiel_class_id' => $packageContentInfo['materiel_class_id'],
                'materiel_class_name' => $packageContentInfo['materiel_class_name'],
                'materiel_class_no' => $packageContentInfo['materiel_class_no'],
                'materiel_type_id' => $packageContentInfo['type_id'],
                'materiel_name' => $packageContentInfo['materiel_name'],
                'type_name' => $packageContentInfo['type_name'],
                'materiel_no' => $packageContentInfo['materiel_no'],
                'operate_num' => $value['num'],
                'shelf_id' => $packageContentInfo['shelf_id'],
                'location_id' => $packageContentInfo['shelf_location_id'],
                'out_storage_manage_id' => $packageContentInfo['storage_manage_id'],
                'last_storage_num' => $packageContentInfo['in_storage_num'],
                'next_storage_num' => $packageContentInfo['in_storage_num'] - $value['num'],
                'all_id_type' => 2,
                'all_id' => $data['all_id'],
                'user_id' => $data['user_id'],
                'main_id' => $data['main_id'],
                'created_at' => time()
            ];
        }

        batch()->update(new StorageBatchModel, $batchOut, 'id');
        batch()->update(new StorageManageModel, $storageManageOut, 'id');

        LogPackageContentModel::insert($logPackageContent);

        return true;
    }

    static public function breakagePakcageSerial($packageContentInfo, $data, $logId)
    {
        $serialNumber = array_filter(explode(',', $packageContentInfo['serial_number']), function($v) { return $v !== ''; });

        $checkSerialNumber = SerialNumberModel::whereIn('serial_no', $serialNumber)
            ->get()->toArray();

        $serialBreakageArr = [];
        $batchOut = [];
        $storageOut = [];
        $logPackageContent = [];

        foreach($checkSerialNumber as $value) {
            if(!$value['status']) {
                throw new Exception('序列号已被使用，无法进行报损');
            }

            $serialBreakageArr[] = [
                'id' => $value['id'],
                'status' => 0
            ];

            $storageManageInfo = StorageManageModel::where('id', $value['storage_manage_id'])->first();

            if(empty($storageManageInfo)) {
                throw new Exception('无效库存信息，无法报损');
            }

            if($storageManageInfo['in_storage_num'] < 1) {
                throw new Exception('库存数不足，无法报损');
            }

            if($storageManageInfo['virtual_storage_num'] < 1) {
                throw new Exception('可用库存数不足，无法报损');
            }

            $batchInfo = StorageBatchModel::where('storage_manage_id', $storageManageInfo['id'])
                ->where('batch_left_num', '>=', 1)->orderBy('batch_left_num', 'desc')->first();

            if(!empty($batchInfo)) {
                $batchOut[] = [
                    'id' => $batchInfo['id'],
                    'batch_left_num' => $batchInfo['batch_left_num'] - 1,
                ];
            }

            $storageOut[] = [
                'id' => $storageManageInfo['id'],
                'virtual_storage_num' => $storageManageInfo['virtual_storage_num'] - 1,
                'in_storage_num' => $storageManageInfo['in_storage_num'] - 1,
            ];

            $logPackageContent[] = [
                'log_package_id' => $logId,
                'package_id' => $packageContentInfo['package_id'],
                'storage_id' => $packageContentInfo['storage_id'],
                'storage_name' => $packageContentInfo['storage_name'],
                'storage_address' => $packageContentInfo['storage_address'],
                'materiel_class_id' => $packageContentInfo['materiel_class_id'],
                'materiel_class_name' => $packageContentInfo['materiel_class_name'],
                'materiel_class_no' => $packageContentInfo['materiel_class_no'],
                'materiel_type_id' => $packageContentInfo['type_id'],
                'materiel_name' => $packageContentInfo['materiel_name'],
                'type_name' => $packageContentInfo['type_name'],
                'materiel_no' => $packageContentInfo['materiel_no'],
                'operate_num' => 1,
                'shelf_id' => $packageContentInfo['shelf_id'],
                'location_id' => $packageContentInfo['shelf_location_id'],
                'out_storage_manage_id' => $packageContentInfo['storage_manage_id'],
                'last_storage_num' => $packageContentInfo['in_storage_num'],
                'next_storage_num' => $packageContentInfo['in_storage_num'] - 1,
                'all_id_type' => 2,
                'all_id' => $data['all_id'],
                'user_id' => $data['user_id'],
                'main_id' => $data['main_id'],
                'created_at' => time()
            ];
        }

        batch()->update(new SerialNumberModel, $serialBreakageArr, 'id');

        if(!empty($batchOut)) {
            batch()->update(new StorageBatchModel, $batchOut, 'id');
        }

        batch()->update(new StorageManageModel, $storageOut, 'id');

        LogPackageContentModel::insert($logPackageContent);
        return true;
    }

    static public function serialBatchBreakage($batchInfo, $data)
    {
        $batchInfo = json_decode($batchInfo, true);

        $batchOut = [];
        $batchOutLog = [];
        $storageManageOut = [];
        foreach($batchInfo as $value) {
            $batchInfo = StorageBatchModel::where('id', $value['batch_id'])->orderBy('batch_left_num', 'desc')->first();

            if($batchInfo['batch_left_num'] < $value['num']) {
                throw new Exception('批次号:'.$batchInfo['batch_no'].'剩余批次数量不足，当前剩余:'.$batchInfo['batch_left_num']);
            }

            $storageManageInfo = StorageManageModel::where('id', $value['storage_manage_id'])->where('delete_flag', 0)->first();

            if(empty($storageManageInfo)) {
                throw new Exception('无效库存信息,无法报损');
            }

            if($storageManageInfo['in_storage_num'] < $value['num']) {
                throw new Exception('库存数不足，无法报损');
            }

            if($storageManageInfo['virtual_storage_num'] < $value['num']) {
                throw new Exception('可用库存数不足，无法报损');
            }

            $batchOut[] = [
                'id' => $batchInfo['id'],
                'batch_left_num' => $batchInfo['batch_left_num'] - $value['num']
            ];

            $storageManageOut[] = [
                'id' => $storageManageInfo['id'],
                'virtual_storage_num' => $storageManageInfo['virtual_storage_num'] - $value['num'],
                'in_storage_num' => $storageManageInfo['in_storage_num'] - $value['num'],
            ];

            $batchOutLog[] = [
                'type' => 0,
                'storage_batch_id' => $batchInfo['id'],
                'storage_id' => $storageManageInfo['storage_id'],
                'storage_name' => $storageManageInfo['storage_name'],
                'storage_address' => $storageManageInfo['storage_address'],
                'curr_storage_manage_id' => $storageManageInfo['id'],
                'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                'materiel_class_name' => $storageManageInfo['class_name'],
                'materiel_class_no' => $storageManageInfo['class_no'],
                'materiel_type_id' => $storageManageInfo['type_id'],
                'materiel_name' => $storageManageInfo['materiel_name'],
                'type_name' => $storageManageInfo['type_name'],
                'materiel_no' => $storageManageInfo['materiel_no'],
                'operate_num' => $value['num'],
                'last_storage_num' => $storageManageInfo['in_storage_num'],
                'next_storage_num' => $storageManageInfo['in_storage_num'] - $value['num'],
                'sell_price' => $storageManageInfo['materiel_mean_cost'],
                'materiel_mean_cost' => $storageManageInfo['materiel_mean_cost'],
                'user_id' => $data['user_id'],
                'main_id' => $data['main_id'],
                'out_storage_time' => time(),
                'created_at' => time(),
                'all_id_type' => 1,
                'all_id' => $data['all_id'],
                'is_cancel' => 0
            ];
        }

        batch()->update(new StorageBatchModel, $batchOut, 'id');
        batch()->update(new StorageManageModel, $storageManageOut, 'id');

        LogOutStorageModel::insert($batchOutLog);

        return true;
    }



    static public function serialMaterielBreakage($vInfo, $data)
    {   $serialInfo = $vInfo['serial_number'];
        $serialNumber = array_filter(explode(',', $serialInfo), function($v) {return $v !== '';});

       /*  $checkSerialNumber = SerialNumberModel::whereIn('serial_no', $serialNumber)
            ->get()->toArray(); */

            $checkSerialNumber = SerialNumberModel::where([
                /* 'main_id'=>$data['main_id'], */
                'goods_id'=>$vInfo['materiel_type_id']
            ])->whereIn('serial_no', $serialNumber)

            ->get()->toArray();

        $serialBreakageArr = [];
        $storageOut = [];
        $storageOutLog = [];
        $batchOut = [];

        foreach($checkSerialNumber as $value) {
            if(!$value['status']) {
                throw new Exception('序列号已被使用，无法报损');
            }

            $serialBreakageArr[] = [
                'id' => $value['id'],
                'status' => 0
            ];

            $storageManageInfo = StorageManageModel::where('id', $value['storage_manage_id'])->first();

            if(empty($storageManageInfo)) {
                throw new Exception('无效库存信息，无法报损');
            }

            if($storageManageInfo['in_storage_num'] < 1) {
                throw new Exception('库存数不足，无法报损');
            }

            if($storageManageInfo['virtual_storage_num'] < 1) {
                throw new Exception('可用库存数不足，无法报损');
            }

            $batchInfo = StorageBatchModel::where('storage_manage_id', $storageManageInfo['id'])
                ->where('batch_left_num', '>=', 1)->orderBy('batch_left_num', 'desc')->first();

            if(!empty($batchInfo)) {
                $batchOut[] = [
                    'id' => $batchInfo['id'],
                    'batch_left_num' => $batchInfo['batch_left_num'] - 1,
                ];
            }

            $storageOut[] = [
                'id' => $storageManageInfo['id'],
                'virtual_storage_num' => $storageManageInfo['virtual_storage_num'] - 1,
                'in_storage_num' => $storageManageInfo['in_storage_num'] - 1,
            ];

            $storageOutLog[] = [
                'type' => 0,
                'storage_batch_id' => empty($batchInfo['id'])?0:$batchInfo['id'],
                'storage_id' => $storageManageInfo['storage_id'],
                'storage_name' => $storageManageInfo['storage_name'],
                'storage_address' => $storageManageInfo['storage_address'],
                'curr_storage_manage_id' => $storageManageInfo['id'],
                'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                'materiel_class_name' => $storageManageInfo['class_name'],
                'materiel_class_no' => $storageManageInfo['class_no'],
                'materiel_type_id' => $storageManageInfo['type_id'],
                'materiel_name' => $storageManageInfo['materiel_name'],
                'type_name' => $storageManageInfo['type_name'],
                'materiel_no' => $storageManageInfo['materiel_no'],
                'operate_num' => 1,
                'last_storage_num' => $storageManageInfo['in_storage_num'],
                'next_storage_num' => $storageManageInfo['in_storage_num'] - 1,
                'sell_price' => $storageManageInfo['materiel_mean_cost'],
                'materiel_mean_cost' => $storageManageInfo['materiel_mean_cost'],
                'user_id' => $data['user_id'],
                'main_id' => $data['main_id'],
                'out_storage_time' => time(),
                'created_at' => time(),
                'all_id_type' => 1,
                'all_id' => $data['all_id'],
                'is_cancel' => 0
            ];
        }

        batch()->update(new SerialNumberModel, $serialBreakageArr, 'id');
        batch()->update(new StorageManageModel, $storageOut, 'id');

        if(!empty($batchOut)) {
            batch()->update(new StorageBatchModel, $batchOut, 'id');
        }

        LogOutStorageModel::insert($storageOutLog);
        return true;
    }

    static public function overflowAgree($data, $mainInfo)
    {
        $newSerialNumber = [];
        $existStorage = [];
        $existSerialLogArr = [];
        $newSerialLogArr = [];
        foreach($mainInfo['goods_info'] as $value) {
            if($data['is_use_shelf']) {
                $checkStorageInfo = StorageManageModel::where('type_id', $value['materiel_type_id'])
                    ->where('location_id', $value['shelf_location_id'])->first();
            }
            else {
                $checkStorageInfo = StorageManageModel::where('type_id', $value['materiel_type_id'])
                ->where('storage_id',$value['warehouse_id'])
                ->first();
            }

            if(empty($checkStorageInfo)) {
                $shelfInfo = StorageShelfModel::where([
                    'storage_id' => $value['warehouse_id'],
                    'shelf_type' => 1
                ])->first();

                $locationInfo = StorageShelfLocationModel::where([
                    'shelf_id' => $shelfInfo['id'],
                    'location_type' => 1
                ])->first();

                $insertId = StorageManageModel::insertGetId([
                    'materiel_class_id' => $value['materiel_class_id'],
                    'materiel_class_name' => $value['class_name'],
                    'materiel_class_no' => $value['class_no'],
                    'type_id' => $value['materiel_type_id'],
                    'materiel_name' => $value['name'],
                    'type_name' => $value['type_name'],
                    'materiel_no' => $value['materiel_no'],
                    'storage_id' => $value['warehouse_id'],
                    'storage_name' => $value['warehouse'],
                    'storage_address' => $value['warehouse'],
                    'in_storage_num' => $value['num'],
                    'virtual_storage_num' => $value['num'],
                    'shelf_id' => empty($value['shelf_id'])?$shelfInfo['id']:$value['shelf_id'],
                    'location_id' => empty($value['location_id'])?$locationInfo['id']:$value['location_id'],
                    'main_id' => $data['main_id'],
                    'in_storage_time' => time()
                ]);

                $batchNo = $data['batch_title'].date('YmdHis', time()).mt_rand(1000, 9999).'0';
                $checkBatchNo = StorageBatchModel::where('main_id', $data['main_id'])
                    ->where('batch_no', $batchNo)->first();

                do {
                    $batchNo = $data['batch_title'].date('YmdHis', time()).mt_rand(1000, 9999).'0';
                }
                while(!empty($checkBatchNo));

                $batchId = MaterielService::createBatchInfoGetId(
                    $batchNo,
                    $insertId,
                    0,
                    $value['num'],
                    0,
                    $data['main_id']
                );

                if(!empty($value['serial_number'])) {
                    $serialNumber = array_filter(explode(',', $value['serial_number']), function($v) {return $v !== '';});
                    $serialNumber = array_filter(explode(',', $value['serial_number']), function($v) {return $v !== '';});



                        $checkSerialNumber = SerialNumberModel::where('status', 1)
                        ->where('goods_id',$value['materiel_type_id'])
                        /* ->where('main_id',$data['main_id']) */

                        ->whereIn('serial_no', $serialNumber)
                        ->first();

                    if(!empty($checkSerialNumber)) {
                        throw new Exception('序列号已存在，无法报溢');
                    }

                    foreach($serialNumber as $val) {
                        $newSerialNumber[] = [
                            'storage_manage_id' => $insertId,
                            'serial_no' => $val,
                            'goods_id' => $value['materiel_type_id'],

                            'main_id' => $data['main_id']

                        ];
                    }
                }

                $newSerialLogArr[] = [
                    'curr_storage_manage_id' => $insertId,
                    'materiel_type_id' => $value['materiel_type_id'],//物料id
                    'batch_id' => $batchId,//物料id
                    'materiel_name' => $value['name'],//物料名称
                    'type_name' => $value['type_name'],//物料型号
                    'materiel_no' => $value['materiel_no'],//物料编号
                    'materiel_class_id' => $value['materiel_class_id'],//物料二级分类主键名称
                    'materiel_class_name' => $value['class_name'],//物料二级分类名称
                    'materiel_class_no' => $value['class_no'],//物料二级分类编号
                    'type' => 0,//入库日志类型;0:入库;1:调拨入库;2:直接入库;
                    'storage_id' => $value['warehouse_id'],//仓库主键id
                    'storage_name' => $value['warehouse'],//仓库名
                    'storage_address' => $value['warehouse'],//仓库地址
                    'last_storage_id' => 0,//调拨前所在仓库id
                    'operate_num' => $value['num'],//操作数量
                    'last_storage_num' => 0,//操作前库存数
                    'materiel_mean_cost' => $value['cost'],//物料均价
                    'next_storage_num' => $value['num'],//操作后库存数
                    'all_id_type' => 1,//单据类型;0:无;1:报溢;2:退货;3:采购;
                    'in_storage_time' => time(),//入库时间
                    'serial_number' => $value['serial_number'],
                    'shelf_id' => $value['shelf_id'],
                    'location_id' => $value['shelf_location_id'],
                    'all_id' => $data['all_id'],//单据id
                    'user_id' => $data['user_id'],//操作人用户id
                    'main_id' => $data['main_id'],//主账号id
                    'remark' => empty($data['remark'])?'':$data['remark'],
                    'created_at' => time(),
                ];
            }
            else {
                $existStorage[] = [
                    'id' => $checkStorageInfo['id'],
                    'in_storage_num' => $value['num'] + $checkStorageInfo['in_storage_num'],
                    'virtual_storage_num' => $value['num'] + $checkStorageInfo['virtual_storage_num'],
                ];

                $batchNo = $data['batch_title'].date('YmdHis', time()).mt_rand(1000, 9999).'0';
                $checkBatchNo = StorageBatchModel::where('main_id', $data['main_id'])
                    ->where('batch_no', $batchNo)->first();

                do {
                    $batchNo = $data['batch_title'].date('YmdHis', time()).mt_rand(1000, 9999).'0';
                }
                while(!empty($checkBatchNo));

                $batchId = MaterielService::createBatchInfoGetId(
                    $batchNo,
                    $checkStorageInfo['id'],
                    0,
                    $value['num'],
                    0,
                    $data['main_id']
                );

                if(!empty($value['serial_number'])) {
                    $serialNumber = array_filter(explode(',', $value['serial_number']), function($v) {return $v !== '';});

                    $checkSerialNumber = SerialNumberModel::where('status', 1)


                    ->where('goods_id',$value['materiel_type_id'])

                        ->whereIn('serial_no', $serialNumber)
                        ->first();
                    if(!empty($checkSerialNumber)) {
                        throw new Exception('序列号已存在，无法报溢');
                    }

                    foreach($serialNumber as $val) {
                        $newSerialNumber[] = [
                            'storage_manage_id' => $checkStorageInfo['id'],
                            'serial_no' => $val,
                            'main_id' => $data['main_id'],
                            'goods_id' => $value['materiel_type_id']//物料id

                        ];
                    }
                }

                $existSerialLogArr[] = [
                    'curr_storage_manage_id' => $checkStorageInfo['id'],
                    'materiel_type_id' => $value['materiel_type_id'],//物料id
                    'batch_id' => $batchId,//物料id
                    'materiel_name' => $value['name'],//物料名称
                    'type_name' => $value['type_name'],//物料型号
                    'materiel_no' => $value['materiel_no'],//物料编号
                    'materiel_class_id' => $value['materiel_class_id'],//物料二级分类主键名称
                    'materiel_class_name' => $value['class_name'],//物料二级分类名称
                    'materiel_class_no' => $value['class_no'],//物料二级分类编号
                    'type' => 0,//入库日志类型;0:入库;1:调拨入库;2:直接入库;
                    'storage_id' => $value['warehouse_id'],//仓库主键id
                    'storage_name' => $value['warehouse'],//仓库名
                    'storage_address' => $value['warehouse'],//仓库地址
                    'last_storage_id' => 0,//调拨前所在仓库id
                    'operate_num' => $value['num'],//操作数量
                    'last_storage_num' => 0,//操作前库存数
                    'materiel_mean_cost' => $value['cost'],//物料均价
                    'next_storage_num' => $value['num'],//操作后库存数
                    'all_id_type' => 1,//单据类型;0:无;1:报溢;2:退货;3:采购;
                    'in_storage_time' => time(),//入库时间
                    'serial_number' => $value['serial_number'],
                    'shelf_id' => $value['shelf_id'],
                    'location_id' => $value['shelf_location_id'],
                    'all_id' => $data['all_id'],//单据id
                    'user_id' => $data['user_id'],//操作人用户id
                    'main_id' => $data['main_id'],//主账号id
                    'remark' => empty($data['remark'])?'':$data['remark'],
                    'created_at' => time(),
                ];
            }
        }

        LogInStorageModel::insert($existSerialLogArr);
        LogInStorageModel::insert($newSerialLogArr);
        SerialNumberModel::insert($newSerialNumber);

        batch()->update(new StorageManageModel, $existStorage, 'id');

        return ['code' => 0, 'msg' => 'success', 'data' => ''];
    }

    /**
     * 审批拒绝
     * @param $data
     * 2022/9/17 15:20
     * Author: Sun Wu
     * @return array
     */
    static public function refuse($data)
    {
        DB::beginTransaction();
        try {
            CheckModel::where('id', $data['id'])->update(['status' => 1]);
            OverflowBreakageChecksModel::where('o_b_main_id', $data['all_id'])->update(['status' => 2, 'refund_remark' => empty($data['remark'])?'':$data['remark']]);
            OverflowBreakageModel::where('id', $data['all_id'])->update(['status' => 2]);

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(Exception $e) {
            Log::debug('报溢报损审批拒绝异常'.var_export($e->getMessage(), true));
            DB::rollBack();
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }
}
